#!/bin/bash
set -e -o pipefail

triton_docker_version=1.12.6
triton_compose_version=1.9.0

# Check if triton is installed and executable
function checkTritonInstalled () {
    command -v triton >/dev/null 2>&1 || { echo >&2 "Triton CLI tools do not appear to be installed. Please install before continuing."; exit 1; }
}

# Check if curl is installed and executable
function checkCurlInstalled () {
    command -v curl >/dev/null 2>&1 || { echo >&2 "curl is required to complete this installation. Please install before continuing."; exit 1; }
}

# Check if the Docker binary (named triton-docker-helper)
# and Docker Compose (named triton-compose-helper) are installed and executable
function checkDockerInstalled () {
    if 
        [ ! -f /usr/local/bin/triton-docker-helper ] || 
        [ ! -x /usr/local/bin/triton-docker-helper ] ||
        [ "${triton_docker_version}," != "$(/usr/local/bin/triton-docker-helper -v | awk '{print $3}')" ] ||
        [ ! -f /usr/local/bin/triton-compose-helper ] ||
        [ ! -x /usr/local/bin/triton-compose-helper ] ||
        [ "${triton_compose_version}," != "$(/usr/local/bin/triton-compose-helper -v | awk '{print $3}')" ]
    then
        echo 'Additional or updated components are required.'
        echo 'Please run `sudo triton-docker-install` to continue.'
        echo
        exit 1
    fi
}

# Install architecture-specific Docker and Docker Compose binaries
function install () {
    echo "Triton needs to install additional components for Docker and Docker Compose interactions."
    echo "This installation will only happen once."

    # Check if curl is installed and executable
    checkCurlInstalled

    # Install the specific version of Docker for Triton
    rm -Rf /tmp/triton-docker /usr/local/bin/triton-docker-helper
    mkdir -p /tmp/triton-docker
    curl https://get.docker.com/builds/"$(uname -a | awk '{ print $1 }')"/x86_64/docker-${triton_docker_version}.tgz | tar zxvf - -C /tmp/triton-docker
    mv /tmp/triton-docker/docker/docker /usr/local/bin/triton-docker-helper
    rm -Rf /tmp/triton-docker
    chmod +x /usr/local/bin/triton-docker-helper

    echo "The triton-docker-helper is now installed."
    echo

    # Install the specific version of Docker Compose for Triton
    curl -Lo /usr/local/bin/triton-compose-helper https://github.com/docker/compose/releases/download/${triton_compose_version}/docker-compose-"$(uname -a | awk '{ print $1 }')"-x86_64
    chmod +x /usr/local/bin/triton-compose-helper

    echo "The triton-compose-helper is now installed."
    echo
}

# Emit the current Triton profile and time
function currentProfile () {
    if [ -n "$TRITON_PROFILE" ]
    then
        local profile_source='via env var; use `eval "$(triton env <profile name>)"` to change'
    else
        local profile_source='default; use `triton profile set <profile name>` to change'
    fi

    # Get and the user's account information and CloudAPI URL for parsing later
    local triton_account="$(triton account get)"

    echo "Executing in '$(triton profile get | awk 'NR == 1 {print $2}')' (${profile_source})"

    # Check if CNS is enabled, require it
    if [ ! "true" == "$(echo "${triton_account}" | awk -F": " '/^triton_cns_enabled:/{print $2}')" ]
    then
        echo
        tput rev  # reverse
        tput bold # bold
        echo 'Warning! Triton CNS is not enabled.'
        tput sgr0 # clear
        echo
        echo 'Please run the following to activate:'
        echo '  triton account update triton_cns_enabled=true'
        echo
    fi
}

# Set env vars to make using CNS easier
function cnsEnvVars () {

    # If the CNS env vars are already set, don't bother continuing
    if [ -n "$TRITON_CNS_SEARCH_DOMAIN_PUBLIC" ] && [ -n "$TRITON_CNS_SEARCH_DOMAIN_PRIVATE" ]
    then
        return
    fi

    # Get and the user's account information and CloudAPI URL for parsing later
    local triton_account="$(triton account get)"
    local triton_url="$(triton profile get | awk -F"/" '/url:/{print $3}')"

    # Do not continue if the target is not a Triton Public Cloud data center
    if [ ! ".api.joyent.com" == "${triton_url: -15}" ]
    then
        return
    fi

    # Get the user's UUID
    local triton_account_uuid="$(echo "${triton_account}" | awk -F": " '/^id:/{print $2}')"

    # Get current data center name
    # Note: this makes assumptions that work in our public cloud, but might not work elsewhere
    # Further note: set TRITON_CNS_SUFFIX_PUBLIC and TRITON_CNS_SUFFIX_PRIVATE to work around this
    local triton_dc="$(echo "${triton_url}" | awk -F'.' '{print $1}')"

    # Set the CNS base for public and private names
    # Note, this also makes assumptions that only work in our public cloud
    export TRITON_CNS_SEARCH_DOMAIN_PUBLIC="${triton_account_uuid}.${triton_dc}.triton.zone"
    export TRITON_CNS_SEARCH_DOMAIN_PRIVATE="${triton_account_uuid}.${triton_dc}.cns.joyent.com"
}

# Run all checks
function checkAll () {
    checkTritonInstalled &&
    checkDockerInstalled
}

# Special case handling if the sub-command is `profile`
if [ "profile" == "$1" ]
then
    currentProfile
    exit 1
fi

# Change behavior based on the calling name of this executable
case "$(basename $0)" in
    triton-docker)
        checkAll &&
        eval "$(triton env)" &&
        cnsEnvVars &&
        exec /usr/local/bin/triton-docker-helper $@
        ;;
    triton-compose)
        checkAll &&
        eval "$(triton env)" &&
        export COMPOSE_HTTP_TIMEOUT=750 &&
        cnsEnvVars &&
        exec /usr/local/bin/triton-compose-helper $@
        ;;
    triton-docker-install)
        install
        ;;
esac
